

#ifndef SCOPEDLOCK_HPP
#define SCOPEDLOCK_HPP

#include "Concurrent/Mutex.hpp"
#include "Global/MyEngine.hpp"
#include "Pattern/Uncopyable.hpp"

namespace My
{
    /**
    *   @brief ScopedLock is a convenience class that simplifies locking and unlocking a Mutex.
    *
    *   <p>Locking and unlocking a Mutex in complex functions and statements or in exception
    *   handling code is error-prone and difficult to debug. ScopedLock can be used in such
    *   situations to ensure that the state of the Mutex is always well-defined. ScopedLock
    *   should be created within a function where a Mutex needs to be locked. The Mutex is locked
    *   when ScopedLock is created. The Mutex will be unlocked when the ScopedLock is destroyed.</p>
    *
    *   @see Mutex
    */
    class MY_SHARED ScopedLock : private Uncopyable
    {
    public:
        /**
        *   @brief Constructor.
        *   @param mutex Mutex to lock.
        *
        *   <p>Mutex is locked on construction.</p>
        *
        *   @see ~ScopedLock()
        */
        ScopedLock(Mutex& mutex);

        /**
        *   @brief Destructor.
        *
        *   <p>Mutex is unlocked on destruction.</p>
        *
        *   @see ~ScopedLock()
        */
        ~ScopedLock();

        /**
        *   @brief Get the handled Mutex.
        */
        Mutex& GetMutex() const;

    private:
        Mutex& m_Mutex;
    };
}

#endif // SCOPEDLOCK_HPP
